//
// Created by lenovo on 2024/7/5.
//
#include "./GameObj.h"
#include "../Msg/Message.h"
namespace Game::Obj{
    // Enemy implementation
    Enemy::Enemy(Player* target)
            : target(target), speed(100.0f), position(0, 0), scale(1, 1), animaR(nullptr), collider(nullptr) {
        position = Vector2f(200, 200); // Example position
        scale = Vector2f(120, 120); // Example scale
        speed = 80; // Example speed

        animaR = Graphic::AnimationBuilder()
                .addPath(IMG_RESOURCE + "enemy_left_0.png")
                .addPath(IMG_RESOURCE + "enemy_left_1.png")
                .addPath(IMG_RESOURCE + "enemy_left_2.png")
                .addPath(IMG_RESOURCE + "enemy_left_3.png")
                .addPath(IMG_RESOURCE + "enemy_left_4.png")
                .addPath(IMG_RESOURCE + "enemy_left_5.png")
                .position(position)
                .interval(1)
                .opacity(0.8f)
                .loop(true)
                .pause()
                .play()
                .scale(scale)
                .build();

        animaL = Graphic::AnimationBuilder()
                .addPath(IMG_RESOURCE + "enemy_right_0.png")
                .addPath(IMG_RESOURCE + "enemy_right_1.png")
                .addPath(IMG_RESOURCE + "enemy_right_2.png")
                .addPath(IMG_RESOURCE + "enemy_right_3.png")
                .addPath(IMG_RESOURCE + "enemy_right_4.png")
                .addPath(IMG_RESOURCE + "enemy_right_5.png")
                .position(position)
                .interval(1)
                .opacity(0.8f)
                .loop(true)
                .pause()
                .play()
                .scale(scale)
                .build();

        collider = new CircleCollider;

        adjustCollider();
    }

    void Enemy::update(float delta) {
        animaR->update(delta);
        animaL->update(delta);
        if (target) {
            updateDirection();
            setPosition(position += direction * speed * delta);
//            cout << "Direction : (" << direction.x <<" , " << direction.y << " )" << endl ;
        }
    }

    void Enemy::onCollision(GameObj* obj) {
        // Handle collision with other objects
        if (auto* player = dynamic_cast<Player*>(obj)){
            auto& eBus = Game::Msg::MsgBus::getInstance();
            eBus.post(
                    new Msg::DestroyMsg(this)
            );
        }
        else if (auto* enemy = dynamic_cast<Enemy*>(obj)) {
            // 处理敌人之间的碰撞，简单分离逻辑
            Vector2f diff = getPosition() - enemy->getPosition();
            float distance = sqrt(diff.x * diff.x + diff.y * diff.y);
            if (distance < collider->getRadius() + enemy->collider->getRadius()) {
                // 将两个敌人分开
                Vector2f separation = diff / distance * (collider->getRadius() + enemy->collider->getRadius() - distance);
                setPosition(getPosition() + separation / 2.0f);
                enemy->setPosition(enemy->getPosition() - separation / 2.0f);
            }
        }
        else if (auto* bullet = dynamic_cast<Bullet*>(obj)){
            destroy();
        }
    }

    void Enemy::destroy() {
        Msg::MsgBus::getInstance().post(
                new Msg::DestroyMsg(this)
        );
    }

    void Enemy::draw(sf::RenderWindow& window) {
        // Draw the enemy
        if (target->position.x > this->position.x)
            window.draw(*animaL);

        else
            window.draw(*animaR);
    }

    void Enemy::setPosition(Vector2f newPosition) {
        position = newPosition;
        animaR->setPosition(position);
        animaL->setPosition(position);
//        collider->setPosition(position);
        adjustCollider();
    }

    void Enemy::setScale(Vector2f newScale) {
        scale = newScale;
        animaR->setScale(newScale);
        animaL->setScale(newScale);
        adjustCollider();
    }

    Vector2f normalize(Vector2f v){
        float length = std::sqrt(v.x * v.x + v.y * v.y);
        if (length != 0.0f) {
//            v.x /= length;
//            v.y /= length;
            return Vector2f ({
                                     v.x / length ,
                                     v.y / length
                             });
        }
        throw std::logic_error("Vector 0 cannot be normalized");
    }

    void Enemy::updateDirection() {
        Vector2f toPlayer = target->position - position;
        try{
            direction = normalize(toPlayer);
        }catch (exception e){
            direction = Vector2f ({0,0});
        }

    }

    /**
     * @param
     * 别问,问就是试出来的
     */
    void Enemy::adjustCollider() {
        collider->setPosition(position + Vector2f(scale.x / 2.1, scale.y / 2.2));
//        collider->setPosition(position);
        collider->setRadius(scale.x * (float)(35.0/120.0));
    }


}